/*
 * Authors: Alex Attar & Kevin El Hage
 * ID: 9765727
 * Date: 9/3/2012
 * 
 */

package taskManagerSystem.ModelSubsystem;

import java.util.Vector;

/*
 * The Model class manages the model of the system and all manipulation of data.
 */
public class Model {

	private Vector<Task> tasks;
	private Vector<Person> people;
	private boolean changed = false; // Keeps track of whether the model has been changed since the last save
	
	/*
	 * The constructor simply ensures that the model is empty when it is created.
	 */
	public Model(){
		clearData();
	}
	
	public void clearData(){
		tasks = new Vector<Task>();
		people = new Vector<Person>();
		changed = false;
	}
	
	// Getters for the tasks and people
	public Vector<Task> getTasks(){
		return tasks;
	}

	public Vector<Person> getPeople(){
		return people;
	}
	
	/*
	 * When a task is added, the model ensures that the ID used is unique to the new task.
	 */
	public void addTask(){
		int taskID = tasks.size()+1;
		while (findTaskIndex(taskID) >= 0)
			taskID++;
		tasks.add(new Task(taskID, "", "", 0, "", "", "", 0, 0));
		buildPeopleFromTasks();
		changed = true;
	}
	
	public void removeTask(int taskID){
		int index = findTaskIndex(taskID);
		tasks.remove(index);
		buildPeopleFromTasks();
		changed = true;
	}
	
	/*
	 * When a task is updated, the model ensures that the task being updated exists.
	 * Then, the appropriate field is determined and the task's setter is called.
	 */
	public void updateTask(int taskID, int column, Object newValue){
		int index = findTaskIndex(taskID);
		if (index >= 0 && index < tasks.size()){
			Task task = tasks.get(index);
			switch (column){
			case 0:
				break;
			case 1:
				task.setTitle((String) newValue);
				break;
			case 2:
				task.setDescription((String) newValue);
				break;
			case 3:
				task.setDuration(Integer.parseInt((String) newValue));
				break;
			case 4:
				task.setDeliverable((String) newValue);
				break;
			case 5:
				task.setDeadlineDate((String) newValue);
				break;
			case 6:
				task.setPerson((String) newValue);
				break;
			case 7:
				// if the parent id does exist AND parent id not equal to child id 
				// AND newParent's Id not equal to one of this task's child's id --> add
				int newParent = Integer.parseInt((String)newValue);
				if( newParent == 0 || (findTaskIndex(newParent) !=-1 
					&& tasks.get(findTaskIndex(newParent)).getParentTaskId() != taskID
					&& newParent != taskID))
				{
					task.setParentTaskId(newParent);
				}
				break;
			default:
				break;
			}
			buildPeopleFromTasks();
			changed = true;
		}
	}
	
	/*
	 * Loading and saving are performed by the IOHandler class.
	 */
	public void loadTasks(String filename){
		tasks = IOHandler.loadTasksFile(filename);
		changed = false;
	}
	
	public void saveData(String filename){
		if (filename.endsWith(".xml")){
			filename = filename.substring(0, filename.length()-4);
		}
		IOHandler.saveTaskFile(tasks, filename + ".xml");
		IOHandler.savePersonFile(people, filename + ".txt");
		changed = false;
	}
	
	/*
	 * The existing people are determined by the tasks assigned to them.
	 * As such, whenever a task is created, deleted or modified the list of 
	 * people is updated to reflect the change. 
	 */
	public void buildPeopleFromTasks(){
		people = new Vector<Person>();
		for(int i=0; i!=tasks.size(); i++){
			Task task = tasks.get(i);
			String person = task.getPerson();
			if (person != null && !person.equals("")){
				int personIndex = findPersonIndex(person);
				if (personIndex < 0){
					Person p = new Person(person, task.getDuration(), task.getTitle());
					people.add(p);
				}
				else {
					Person p = people.get(personIndex);
					p.setTotalHours(task.getDuration());
					p.setListOfTasks(task.getTitle());
					people.set(personIndex, p);
				}
			}
		}
	}

	/*
	 * findTaskIndex determines the index of a task in the tasks Vector from the id of the task.
	 * A task's ID is not necessarily the same as its index, making this method necessary.
	 */
	private int findTaskIndex(int id){
		for(int i=0; i!=tasks.size(); i++){
			Task task = tasks.get(i);
			if (task.getTaskID() == id)
				return i;
		}
		return -1;
	}
	
	private int findPersonIndex(String name){
		if (name == null || name.equals(""))
			return -1;
		for(int i=0; i!= people.size(); i++){
			if (name.equals(people.get(i).getName()))
				return i;
		}
		return -1;
	}
	
	// Getter for the changed member.
	public boolean hasChanged(){
		return changed;
	}
}
